package com.house.filter;

import com.alibaba.fastjson.JSON;
import com.house.common.BaseContext;
import com.house.common.R;
import com.house.entity.User;
import com.house.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@WebFilter(filterName = "LoginFilter", urlPatterns = "/*")
public class LoginFilter implements Filter {

    @Autowired
    private RedisUtil redisUtil;

    //路径匹配器，支持通配符
    public static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        if (response != null) {
            addHeadersFor200Response(response, request);
        }
        String requestURI = request.getRequestURI();
        String[] greenLights = {
                "/user/login",
                "/dev/**",
                "/common/**"
        };
        boolean isCheck = check(greenLights, requestURI);
        if(isCheck){
            filterChain.doFilter(request,response);
            return;
        }
        String token = request.getHeader("token");
        if (token == null) {
            response.getWriter().write(JSON.toJSONString(R.error("未登录!", -1)));
            // 5、如果未登录则返回未登录结果，通过输出流方式向客户端页面响应数据
            return;
        }
        String userId = redisUtil.getCacheObject(token);
        if (userId == null) {
            response.getWriter().write(JSON.toJSONString(R.error("认证已过期，请重新认证!", -1)));
            // 5、如果未登录则返回未登录结果，通过输出流方式向客户端页面响应数据
            return;
        }
        User user = redisUtil.getCacheObject(userId);
        if (user == null) {
            response.getWriter().write(JSON.toJSONString(R.error("认证已过期，请重新认证!", -1)));
            // 5、如果未登录则返回未登录结果，通过输出流方式向客户端页面响应数据
            return;
        }
        BaseContext.setThreadUserId(user.getId());
        filterChain.doFilter(request,response);
        // 放行了
    }
    private void addHeadersFor200Response(HttpServletResponse response, HttpServletRequest request) {
        String origin = request.getHeader("Origin");
        response.addHeader("Access-Control-Allow-Origin", origin);
        response.setCharacterEncoding("UTF-8");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Cookie, token");
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        response.addHeader("Access-Control-Max-Age", "1728000");
        response.addHeader("Access-Control-Allow-Credentials", "true");
    }
    /**
     * 路径匹配，检查本次请求是否需要放行
     * @param urls
     * @param requestURI
     * @return
     */
    public boolean check(String[] urls,String requestURI){
        for (String url : urls) {
            boolean match = PATH_MATCHER.match(url, requestURI);
            if(match){
                return true;
            }
        }
        return false;
    }
}
